/* * Copyright 2016 Bekwam, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.bekwam.examples.javafx.dynamic.app_core; import javafx.application.Platform; import javafx.beans.property.SimpleObjectProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.concurrent.Task; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.control.*; import javafx.scene.control.Alert.AlertType; import javafx.stage.FileChooser; import javafx.stage.FileChooser.ExtensionFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.inject.Inject; import javax.inject.Named; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.List; /** * JavaFX Controller for Preferences screen * * @author carl * */ public class PreferencesController { private Logger logger = LoggerFactory.getLogger(PreferencesController.class); @FXML TextField tfJARFolder; @FXML ListView<Path> lvSubApps; @FXML ListView<File> lvJARs; @Inject @Named("SubAppFolder") File subappFolder; @Inject @Named("SubAppJars") ObservableList<Path> subappJars; @Inject @Named("StartupCommandsFullPath") String startupCommandsFullPath; @FXML public void initialize() { lvSubApps.itemsProperty().bind( new SimpleObjectProperty<>(subappJars) ); } @FXML public void browse(ActionEvent evt) { if( logger.isDebugEnabled() ) { logger.debug("[BROWSE]"); } FileChooser fileChooser = new FileChooser(); fileChooser.setTitle("Select JARs"); fileChooser.getExtensionFilters().addAll( new ExtensionFilter("JAR Files", "*.jar", "*.zip") ); List<File> selectedFiles = fileChooser.showOpenMultipleDialog(((Button)evt.getSource()).getScene().getWindow()); if( selectedFiles != null ) { lvJARs.getItems().clear(); lvJARs.setItems( FXCollections.observableArrayList(selectedFiles) ); } } @FXML public void importJARs() { if( logger.isDebugEnabled() ) { logger.debug("[IMPORT] importing into " + subappFolder.getName()); } List<File> selectedFiles = lvJARs.getSelectionModel().getSelectedItems(); if( selectedFiles == null || selectedFiles.isEmpty() ) { Alert alert = new Alert(AlertType.WARNING); alert.setTitle("Import"); alert.setHeaderText("Select JARs"); alert.setContentText("No JAR files selected for import"); alert.showAndWait(); } else { Task<Void> task = new Task<Void>() { @Override protected Void call() throws Exception { for( File sf : selectedFiles ) { Path sf_p = sf.toPath(); Path target_p = Paths.get(subappFolder.getAbsolutePath(), sf.getName()); if (logger.isDebugEnabled()) { logger.debug("[IMPORT] importing " + sf_p + " to " + target_p); } // // It would be a good idea to validate a signature here to // prove that the code is coming from a known source. // // Also, SubApp validation should be here to make sure that // the JAR is a valid SubApp. // Files.copy(sf_p, target_p, StandardCopyOption.REPLACE_EXISTING); Platform.runLater( () -> { subappJars.add( target_p ); }); } return null; } @Override protected void failed() { super.failed(); logger.error( "error importing", getException()); Alert alert = new Alert(AlertType.ERROR); alert.setTitle("Import Error"); alert.setHeaderText( getException().getClass().getName() ); alert.setContentText( getException().getMessage() ); alert.showAndWait(); } }; new Thread(task).start(); } } @FXML public void uninstall() { List<Path> selectedFiles = lvSubApps.getSelectionModel().getSelectedItems(); if (selectedFiles == null || selectedFiles.isEmpty()) { Alert alert = new Alert(AlertType.WARNING); alert.setTitle("Uninstall"); alert.setHeaderText("Select JARs"); alert.setContentText("No JAR files selected to uninstall"); alert.showAndWait(); } else { Alert conf = new Alert(AlertType.CONFIRMATION); conf.setTitle("Uninstall"); conf.setHeaderText("Uninstall JARs?"); String ct = ""; for( Path sp : selectedFiles ) { ct += sp.getFileName(); ct += "\n"; } conf.setContentText( ct ); conf.showAndWait() .filter(response -> response == ButtonType.OK) .ifPresent(response -> { Task<Void> task = new Task<Void>() { @Override protected Void call() throws Exception { for( Path sf : selectedFiles ) { // // Delete command is deferred b/c holding on to file handled since it was // loaded // try ( BufferedWriter bw = new BufferedWriter(new FileWriter(startupCommandsFullPath, true)) ) { bw.write("D " + sf.toAbsolutePath().toString()); bw.newLine(); } catch(IOException exc) { logger.error("can't write command to file " + startupCommandsFullPath, exc); } Platform.runLater( () -> subappJars.remove(sf) ); } return null; } @Override protected void succeeded() { super.succeeded(); Alert alert = new Alert(AlertType.INFORMATION); alert.setTitle("Uninstall"); alert.setHeaderText("Uninstall Successful"); alert.setContentText("You need to restart the app for the install to take effect."); alert.showAndWait(); } @Override protected void failed() { super.failed(); logger.error( "delete task failed", getException()); } }; new Thread(task).start(); } ); } } }